package cn.shop.admin.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.SaSessionCustomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.shop.admin.entity.excel.FrontUserExcel;
import cn.shop.admin.req.ClearInfoReq;
import cn.shop.admin.req.EditPlayerLevelReq;
import cn.shop.admin.req.FrontUserQueryReq;
import cn.shop.admin.req.UpdateBalanceReq;
import cn.shop.admin.service.BackSettingService;
import cn.shop.admin.service.FrontUserService;
import cn.shop.admin.service.RecordService;
import cn.shop.base.MyPage;
import cn.shop.transcation.backSetting.entity.BackSetting;
import cn.shop.transcation.detail.entity.TransactionDetail;
import cn.shop.transcation.frontUserModule.FrontUser;
import cn.shop.transcation.rechargerecord.entity.Record;
import cn.shop.utils.ApiResult;
import cn.shop.utils.constant.SMSVerificationCode;
import cn.shop.utils.constant.SystemSettingConstant;
import cn.shop.utils.enums.TransactionState;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

/**
 * 玩家查询接口
 *
 * @author jzw
 * @since 2022-02-23 09:39:05
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/api/v1/frontUser")
public class FrontUserController {

	/**
	 * 服务对象
	 */
	@Resource
	private FrontUserService frontUserService;

	@Resource
	private RecordService recordService;

	@Resource
	private BackSettingService backSettingService;

	/**
	 * 分页查询所有数据
	 *
	 * @param page      分页对象
	 * @param req 查询实体
	 * @return 所有数据
	 * @author jzw
	 * @since 2022-02-23 09:39:05
	 */
	@GetMapping("queryByPage")
	public ApiResult<MyPage<FrontUser>> queryByPage(MyPage<FrontUser> page, FrontUserQueryReq req) {
		return ApiResult.success(frontUserService.queryFrontUser(page, req));
	}

	/**
	 * 查询玩家绑定的游戏角色
	 *
	 * @param id 玩家id
	 * @return 所有数据
	 * @author jzw
	 * @since 2022-02-23 09:39:05
	 */
	@GetMapping("queryAllRole")
	public ApiResult<List<Map<String, Object>>> queryAllRole(Long id) {
		return ApiResult.success(frontUserService.queryAllRole(id));
	}

	/**
	 * 给玩家充值 总管理员才能充值
	 *
	 * @return 所有数据
	 * @author jzw
	 * @since 2022-02-23 09:39:05
	 */
	@PutMapping("setBalance")
	@SaCheckRole("ROOTUSER")
	public ApiResult<Map<String, Object>> update(@RequestBody UpdateBalanceReq frontUser) {
		BackSetting backSetting = backSettingService.getOneByKey(SystemSettingConstant.ADMIN_TRANSACTION_PASSWORD);
		if (StrUtil.isBlank(backSetting.getValue())) {
			return ApiResult.fail("请设置交易密码");
		}
		if (!DigestUtil.bcryptCheck(frontUser.getPassword(), backSetting.getValue())) {
			return ApiResult.fail("交易密码不正确");
		}
		FrontUser frontUser1 = frontUserService.getById(frontUser.getId());
		if (!frontUser1.getAdvanced()) {
			return ApiResult.fail("当前玩家非高级玩家,无法充值");
		}
		LambdaUpdateWrapper<FrontUser> updateWrapper = Wrappers.lambdaUpdate();
		updateWrapper.eq(FrontUser::getId, frontUser.getId()).setSql("balance = balance + " + frontUser.getBalance());
		boolean isSuccess = frontUserService.update(updateWrapper);
		if (isSuccess) {
			Record record = new Record();
			record.setAmount(frontUser.getBalance());
			record.setActualAmount(record.getAmount());
			record.setBalance(frontUser1.getBalance().add(frontUser.getBalance()));
			record.setChannel("手动充值");
			record.setChannelId(0L);
			record.setPlayerId(frontUser.getId());
			record.setPlayerName(frontUser1.getAccount());
			record.setState(TransactionState.MANUAL);
			record.setType(0);
			boolean s = recordService.save(record);
			if (!s) {
				log.info("手动充值记录保存失败 {}", record);
			}
		}
		return ApiResult.result(isSuccess);
	}

	/**
	 * 清除玩家实名信息
	 * @param req
	 * @return
	 */
	@PutMapping("/clearIdentity")
	public ApiResult<Map<String, Object>> clearIdNo(@Validated @RequestBody ClearInfoReq req) {
		BackSetting backSetting = backSettingService.getOneByKey(SystemSettingConstant.ADMIN_TRANSACTION_PASSWORD);
		if (StrUtil.isBlank(backSetting.getValue())) {
			return ApiResult.fail("请设置交易密码");
		}
		if (!DigestUtil.bcryptCheck(req.getPassword(), backSetting.getValue())) {
			return ApiResult.fail("交易密码不正确");
		}

		LambdaUpdateWrapper<FrontUser> updateWrapper = Wrappers.lambdaUpdate();
		updateWrapper.eq(FrontUser::getId, req.getId())
				.setSql("phone = null")
				.setSql("name = null")
				.setSql("identity_card = null");
		return ApiResult.result(frontUserService.update(updateWrapper));
	}

	/**
	 * 设置玩家级别
	 *
	 * @return 所有数据
	 * @author jzw
	 * @since 2022-02-23 09:39:05
	 */
	@PutMapping("setPlayerLevel")
	@SaCheckRole("ROOTUSER")
	public ApiResult<Map<String, Object>> setPlayerLevel(@RequestBody EditPlayerLevelReq frontUser) {
		SaSession session = SaSessionCustomUtil.getSessionById(SMSVerificationCode.TRANSACTION_PASSWORD_KEY + frontUser.getPhone());
		if (session != null) {
			String code = (String) session.get("code");
			if (code != null && code.equalsIgnoreCase(frontUser.getCode())) {
				BackSetting backSetting = backSettingService.getOneByKey(SystemSettingConstant.ADMIN_TRANSACTION_PASSWORD);
				if (StrUtil.isBlank(backSetting.getValue())) {
					return ApiResult.fail("请设置交易密码");
				}
				if (!DigestUtil.bcryptCheck(frontUser.getPassword(), backSetting.getValue())) {
					return ApiResult.fail("交易密码不正确");
				}
				LambdaUpdateWrapper<FrontUser> updateWrapper = Wrappers.lambdaUpdate();
				updateWrapper.eq(FrontUser::getId, frontUser.getId()).setSql("advanced = not advanced ");
				session.logout();
				return ApiResult.result(frontUserService.update(updateWrapper));
			}
		}
		return ApiResult.fail("验证码不正确");
	}

	/**
	 * 设置玩家为是否风险
	 *
	 * @param frontUser
	 * @return 返回结果
	 */
	@PutMapping("/risk")
	public ApiResult<Map<String, Object>> risk(@RequestBody FrontUser frontUser) {
		FrontUser update = new FrontUser();
		update.setId(frontUser.getId());
		update.setRisk(frontUser.getRisk());
		return ApiResult.result(frontUserService.updateById(update));
	}

	/**
	 * 查看玩家已绑定的提现账号
	 *
	 * @param uid 玩家编号
	 * @return 返回结果
	 */
	@GetMapping("/bindAccount/{uid}")
	public ApiResult<Map<String, Object>> accountList(@PathVariable long uid) {
		return ApiResult.success(frontUserService.bindAccountList(uid));
	}

	/**
	 * 查询玩家交易记录
	 *
	 * @param page 分页对象
	 * @return 所有数据
	 * @author jzw
	 * @since 2022-02-23 09:39:05
	 */
	@GetMapping("queryRecordByPage")
	public ApiResult<MyPage<TransactionDetail>> queryRecordByPage(MyPage<TransactionDetail> page, Long id) {
		return ApiResult.success(frontUserService.queryRecordByPage(page, id));
	}

	/**
	 * 导出用户
	 *
	 * @throws IOException 异常
	 */
	@GetMapping("/export")
	public void export(HttpServletResponse response) throws IOException {
		setExcelRespProp(response, "玩家列表");
		List<FrontUserExcel> list = frontUserService.allUser();
		EasyExcel.write(response.getOutputStream())
				.head(FrontUserExcel.class)
				.excelType(ExcelTypeEnum.XLSX)
				.sheet("玩家列表")
				.doWrite(list);
	}

	/**
	 * 设置excel下载响应头属性
	 */
	private void setExcelRespProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		response.setCharacterEncoding("utf-8");
		String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
		response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
	}

}

